/**
 * @File Name: heaptimer.h
 * @brief  HTTP连接 定时器的实现 HeapTimer
 * @Author : beyon_sir email:caoboyang.chn@gmail.com
 * @Version : 1.0
 * @Create Date : 2022-11-21
 * 
 */
#ifndef HEAP_TIMER_H
#define HEAP_TIMER_H

#include <queue>
#include <unordered_map>
#include <time.h>
#include <algorithm>
#include <arpa/inet.h> 
#include <functional> 
#include <assert.h> 
#include <chrono>
#include "../log/log.h"

typedef std::function<void()> TimeoutCallBack;
typedef std::chrono::high_resolution_clock Clock;
typedef std::chrono::milliseconds MS;
typedef Clock::time_point TimeStamp;

struct TimerNode {
    int id;                                 // 该定时器对应的客户端连接文件描述符fd
    TimeStamp expires;                      // 超时时间
    TimeoutCallBack cb;                     // 回调函数
    bool operator<(const TimerNode& t) {    // 根据TimerNode中的超时时间来决定先后顺序(建立小根堆)
        return expires < t.expires;
    }
};
class HeapTimer {
public:
    HeapTimer() { heap_.reserve(64); }

    ~HeapTimer() { clear(); }
    
    void adjust(int id, int newExpires);

    void add(int id, int timeOut, const TimeoutCallBack& cb);

    void doWork(int id);

    void clear();

    void tick();

    void pop();

    int GetNextTick();

private:
    void del_(size_t i);                                        // 删除索引对应的元素
    
    void siftup_(size_t i);                                     // 该节点向上调整(添加新元素 维持小根堆结构)

    bool siftdown_(size_t index, size_t n);                     // 该节点向下调整(维持小根堆结构)

    void SwapNode_(size_t i, size_t j);                         // 交换节点

    std::vector<TimerNode> heap_;                               // 定时器的容器 

    std::unordered_map<int, size_t> ref_;                       // 保存id(文件描述符fd)和索引的哈希映射
};

#endif //HEAP_TIMER_H